using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class WindowRoot : MonoBehaviour
{
    public bool EnableCompShow; //是否需要开启编辑器的组合Comp效果显示
    public WindowLayer WindowLayer;
    public UIComp CompLayer;
    protected NetSvc mNetSvc;
    protected ResSvc mResSvc;
    protected UISvc mUISvc;
    protected EvtSvc mEvtSvc;
    protected AudioSvc mAudioSvc;
    protected PERoot mRoot;
    protected AcctSystem mAcctSystem;
    protected readonly Dictionary<int, WindowRoot> mWindowDic = new Dictionary<int, WindowRoot>();

    public virtual void InitWindow()
    {
        mRoot = PERoot.Instance;
        mUISvc = mRoot.UIService;
        mResSvc = mRoot.ResService;
        mEvtSvc = mRoot.EvtService;
        mNetSvc = mRoot.NetService;
        mAudioSvc = mRoot.AudioService;
        mAcctSystem = mRoot.AcctSystem;


        for (int i = 0; i < transform.childCount; i++)
        {
            GameObject comp = transform.GetChild(i).gameObject;
            if (comp.name.EndsWith("Comp"))
            {
                GameObject go = null;
                if (comp.transform.childCount == 0)
                {
                    go = mResSvc.LoadAsset($"{PathDefine.CompPath}{comp.name}");
                    go.transform.SetParent(comp.transform);
                    go.transform.localPosition = Vector3.zero;
                    go.transform.localEulerAngles = Vector3.zero;
                    go.transform.localScale = Vector3.one;
                }
                else
                {
                    go = comp.transform.GetChild(0).gameObject;
                }


                WindowRoot windowRoot = go.GetComponent<WindowRoot>();
                Type type = Type.GetType(comp.name);
                if (type != null)
                {
                    int hashCode = type.GetHashCode();
                    if (!mWindowDic.ContainsKey(hashCode))
                    {
                        mWindowDic.Add(hashCode, windowRoot);
                    }

                    windowRoot.SetWindowState(true);
                    this.LogCyan("Add Comp:" + comp.name);
                }
                else
                {
                    this.Error("脚本挂载类型和组件名称不符!");
                }
            }
        }
    }

    public virtual void UnInitWindow()
    {
        mRoot = null;
        mUISvc = null;
        mResSvc = null;
        mEvtSvc = null;
        mNetSvc = null;
        mAcctSystem = null;
        mAudioSvc = null;

        for (int i = 0; i < transform.childCount; i++)
        {
            GameObject comp = transform.GetChild(i).gameObject;
            if (comp.name.EndsWith("Comp"))
            {
                if (comp.transform.childCount == 1)
                {
                    WindowRoot windowRoot = comp.transform.GetChild(0).GetComponent<WindowRoot>();
                    if (windowRoot != null)
                    {
                        windowRoot.SetWindowState(false);
                    }
                    else
                    {
                        this.Error("当前物体上不存在WindowRoot的脚本!");
                    }
                }
            }
        }
    }

    /// <summary>
    /// 设置窗口状态
    /// </summary>
    /// <param name="active"></param>
    public void SetWindowState(bool active)
    {
        if (gameObject.activeSelf != active)
        {
            gameObject.SetActive(active);
        }

        if (active)
        {
            InitWindow();
        }
        else
        {
            UnInitWindow();
        }
    }

    #region //-------------Tool Functions-------------//

    protected void SetActive(GameObject go, bool state = true)
    {
        go.SetActive(state);
    }

    protected void SetActive(Transform trans, bool state = true)
    {
        trans.gameObject.SetActive(state);
    }

    protected void SetActive(RectTransform rectTrans, bool state = true)
    {
        rectTrans.gameObject.SetActive(state);
    }

    protected void SetActive(Image img, bool state = true)
    {
        img.gameObject.SetActive(state);
    }

    protected void SetActive(Text txt, bool state = true)
    {
        txt.gameObject.SetActive(state);
    }

    protected void SetActive(InputField ipt, bool state = true)
    {
        ipt.gameObject.SetActive(state);
    }

    protected void SetText(Transform trans, int num = 0)
    {
        SetText(trans.GetComponent<Text>(), num.ToString());
    }

    protected void SetText(Transform trans, string context = "")
    {
        SetText(trans.GetComponent<Text>(), context);
    }

    protected void SetText(Text txt, int num = 0)
    {
        SetText(txt, num.ToString());
    }

    protected void SetText(Text txt, string context = "")
    {
        txt.text = context;
    }

    protected Transform GetTrans(Transform trans, string name)
    {
        if (trans != null)
        {
            return trans.Find(name);
        }
        else
        {
            return transform.Find(name);
        }
    }

    protected Image GetImage(Transform trans, string path)
    {
        if (trans != null)
        {
            return trans.Find(path).GetComponent<Image>();
        }
        else
        {
            return transform.Find(path).GetComponent<Image>();
        }
    }

    protected Image GetImage(Transform trans)
    {
        if (trans != null)
        {
            return trans.GetComponent<Image>();
        }
        else
        {
            return transform.GetComponent<Image>();
        }
    }

    protected Text GetText(Transform trans, string path)
    {
        if (trans != null)
        {
            return trans.Find(path).GetComponent<Text>();
        }
        else
        {
            return transform.Find(path).GetComponent<Text>();
        }
    }

    private T GetOrAddComponent<T>(GameObject go) where T : Component
    {
        T t = go.GetComponent<T>();
        if (t == null)
        {
            t = go.AddComponent<T>();
        }

        return t;
    }

    protected void OnClick(GameObject go, Action<PointerEventData, object[]> clickCB, params object[] args)
    {
        PEListener listener = GetOrAddComponent<PEListener>(go);
        listener.onClick = clickCB;
        if (args != null)
        {
            listener.args = args;
        }
    }

    protected void OnClickDown(GameObject go, Action<PointerEventData, object[]> clickDownCB, params object[] args)
    {
        PEListener listener = GetOrAddComponent<PEListener>(go);
        listener.onClickDown = clickDownCB;
        if (args != null)
        {
            listener.args = args;
        }
    }

    protected void OnClickUp(GameObject go, Action<PointerEventData, object[]> clickUpCB, params object[] args)
    {
        PEListener listener = GetOrAddComponent<PEListener>(go);
        listener.onClickUp = clickUpCB;
        if (args != null)
        {
            listener.args = args;
        }
    }

    protected void OnDrag(GameObject go, Action<PointerEventData, object[]> dragCB, params object[] args)
    {
        PEListener listener = GetOrAddComponent<PEListener>(go);
        listener.onDrag = dragCB;
        if (args != null)
        {
            listener.args = args;
        }
    }

    #endregion
}